var FMFPLayerUtilsImport = function() {
    /*
     * Copies all the layer records from one version to another
     * @param targetVersionID {string} version sys_id to copy to
     * @param sourceVersionID {string} version sys_id to copy from
     * @return OperationResult.result
     */
     function copyVersionLayers(targetVersionID, sourceVersionID){
         var operationResult = new FMFPOperationResult(true);
 
         //Query source version layers
         var grDuplicateLayers = new GlideRecord(FMConstants.Table.LAYER);
         grDuplicateLayers.addQuery('version', sourceVersionID);
         grDuplicateLayers.query();   
 
         if(grDuplicateLayers.hasNext())
         {
             //Insert all resulting layers as new to the target version
             while(grDuplicateLayers.next()){
                 grDuplicateLayers.version = targetVersionID;
                 grDuplicateLayers.insert();
 
                 if(grDuplicateLayers.isActionAborted()){
                     operationResult.success = false;
                     operationResult.message = "One or more layers were not copied.";
                 }
             }
 
             if(operationResult.success){
                 operationResult.message = "Layers copied successfully";    
             }
         }
         else{
             operationResult.message = "No layers to copy";
         }
 
         return operationResult;
     }
     
    /* STILL USED?
     * Retrieves the layer configuration of the SVG Layer
     * @return OperationResult.result = [{sys_id: {string}, layers: [{string}], order: {string}, geoJSON: { type: {string}, features: [] }}]
     */
     // function getGeoJSONLayerConfiguration() {
     
     //     var geoJsonArr = [];
     //     var gr = new GlideRecord(FMConstants.Table.LAYER_STANDARD_CONFIGURATION);
     //     gr.addQuery('target_format', 'geojson');
     //     gr.addQuery('source', 'autocad');
     //     gr.query();
         
     //     while (gr.next()) {
     //         geoJsonArr.push({
     //             sys_id: gr.getValue('layer_configuration'),
     //             layers: gr.getValue('file_layers').split(','),
     //             order: gr.layer_configuration.default_order,
     //             geoJSON: {
     //                 type: 'FeatureCollection',
     //                 features: [],
     //                 inserts: {}
     //             }
     //         });
     //     }
         
     //     if(geoJsonArr.length > 0){
     //         return new FMFPOperationResult(true, "Operation successful.", geoJsonArr);
     //     }
     //     else{
     //         return new FMFPOperationResult(false, "No layers found.");
     //     }
     // }
 
    /* STILL USED?
     * Retrieves the SVG layer configuration
     * @return OperationResult.result = { layerConfigID: {string}, fileLayers: [{string}] }
     */
     // function getSVGLayerConfiguration() {
 
     //     var gr = new GlideRecord(FMConstants.Table.LAYER_STANDARD_CONFIGURATION);
     //     gr.addQuery('target_format', 'image');
     //     gr.addQuery('source', 'autocad');
     //     gr.query();
     //     if (gr.next()) {

     //         var result = {
     //             order: gr.layer_configuration.default_order,
     //             layerConfigID: gr.getValue('layer_configuration'),
     //             fileLayers: gr.getValue('file_layers').split(',')
     //         };
     //         return new FMFPOperationResult(true, "Operation successful.", result);
     //     }
     //     else{
     //         return new FMFPOperationResult(false, "No layers found.");
     //     }
     // }
     
     function checkoutLayer(layerSysId) {
 
         var result = new FMFPOperationResult(false, 'Operation unsuccessful.');
 
         var grLayers = new GlideRecord(FMConstants.Table.LAYER);
         grLayers.addQuery("sys_id", layerSysId);
         grLayers.setLimit(1);
         grLayers.query();
 
         if (grLayers.next()) {
             if (!grLayers.getValue("checked_out_by") || grLayers.getValue("checked_out_by") == gs.getUserID()) {
                 grLayers.checked_out_by = gs.getUserID();
                 grLayers.check_out_date = new GlideDateTime();
                 grLayers.update();
 
                 result.message = "Layer checked out.";
                 result.success = true;
             } else {
                result.message = "Operation unsuccessful. Layer has been checked by " + grLayers.checked_out_by.getDisplayValue()
                    + " on " + grLayers.getValue("check_out_date") + '.';
                result.success = false;
            }
            return result;
        }

        return result;
    }

    /*
     * Checkout all the layers from a floor
     * @param layers {array of strings} sys_ids of the layers to checkout
     * @param verification {boolean}, if true, a verification if ALL layers can be checked out is made and if true, they are checked out,
     * if false all the layers that are not checked out to anyone are checked out
     */
    function checkoutAllLayers(layers, verification) {
        var layers = layers.split(',');

        if (verification) {

            layersResult = [];

            for (i = 0; i < layers.length; i++) {
                var grLayers = new GlideRecord(FMConstants.Table.LAYER);
                grLayers.addQuery("sys_id", layers[i]);
                grLayers.setLimit(1);
                grLayers.query();
                //Check if is possible to checkout every layer
                layersResult.push(grLayers.next() && (!grLayers.getValue("checked_out_by") || grLayers.getValue("checked_out_by") == gs.getUserID()));
            }
            
            //If there is at least one 'false', return unsuccessful
            for(i=0;i<layersResult.length;i++){
                if(!layersResult[i]){
                    return new FMFPOperationResult(false, 'There are layers checked out to other users.', layersResult);
                }
            }
        }

        layersResult = [];
        for (i = 0; i < layers.length; i++) {
            layersResult.push(checkoutLayer(layers[i]));
        }

        return new FMFPOperationResult(true, 'The layers have been checked out.', layersResult);
    }

    function cancelLayerCheckout(layerSysId) {

        var result = new FMFPOperationResult(false, 'Operation unsuccessful.');

        var grLayers = new GlideRecord(FMConstants.Table.LAYER);
        grLayers.addQuery("sys_id", layerSysId);
        grLayers.setLimit(1);
        grLayers.query();

        if (grLayers.next() && grLayers.getValue("checked_out_by") == gs.getUserID()) {
            grLayers.checked_out_by = '';
            grLayers.check_out_date = '';
            grLayers.update();

            result.message = "Checkout has been canceled.";
            result.success = true;
        }

        return result;
    }

    function getConfiguredLayers(versionSysId, convertionSource, manualConversionLayers) {
        
        var versionRec = new GlideRecord(FMConstants.Table.VERSION);
        if (!versionRec.get(versionSysId)) return;

        var unevaluatedLSC = {
            entitiesByLayer: {},
            layerStandardConfig: []
        };

        var lStdConfigRec = new GlideRecord(FMConstants.Table.LAYER_STANDARD_CONFIGURATION);
        lStdConfigRec.addQuery('layer_standard', versionRec.getValue('layer_standard'));
        lStdConfigRec.addQuery('source', convertionSource);
        lStdConfigRec.orderBy('order');
        lStdConfigRec.query();
        while (lStdConfigRec.next()) {
            var targetFormat = lStdConfigRec.getValue('target_format');
            var layers = convertionSource === 'autocad' ?
                lStdConfigRec.getValue('file_layers').split(',') :
                manualConversionLayers;
            layers.forEach(function (layer) {
                unevaluatedLSC.entitiesByLayer[layer] = [];
            });

            var geoJsonObj = {
                type: 'FeatureCollection',
                features: []
            };

            if(targetFormat === 'geojson') {
                geoJsonObj.inserts = {};
            }

            unevaluatedLSC.layerStandardConfig.push({
                used: false,
                targetFormat: targetFormat,
                sysID: lStdConfigRec.getUniqueValue(),
                fileLayers: layers,
                condition: lStdConfigRec.getValue('object_condition'),
                objectOperation: lStdConfigRec.getValue('objects_operations'),
                geoJSON: geoJsonObj,
                layerConfiguration: {
                    order: lStdConfigRec.layer_configuration.default_order,
                    sysID: lStdConfigRec.getValue('layer_configuration'),
                }
            });
        }

        // if(geoJsonArr.length > 0){
            return new FMFPOperationResult(true, "Operation successful.", unevaluatedLSC);
        // }
        // else{
        //     return new FMFPOperationResult(false, "No layers found.");
        // }
    }

    /*
     * Saves GeoJSONs as a Layer
     * @param versionSysId {string}  sys_id of the version to save to
     * @param geoJSONList [{sys_id: {string}, geoJSON: string}] list of the geoJSONs to be saved with the corresponding layer configuration sys_id
     * @returns the attachmentId OperationResult.result{string}
     */
     function saveLayer(versionSysId, convertedDXF, evaluatedLSC) {
        var layerSysId = '';
        var success = true;
        var message = "Operation succesful.";

        Object.keys(evaluatedLSC).forEach(function (type) {
            evaluatedLSC[type].forEach(function (layerConfig) {
                var gr = new GlideRecord(FMConstants.Table.LAYER);
                gr.addQuery('version', versionSysId);
                gr.addQuery('layer_configuration', layerConfig.layerConfiguration.sysID);
                gr.query();

                if (gr.next()) {
                    gr.setValue('order', layerConfig.layerConfiguration.order);
                    gr.setValue('geojson', JSON.stringify(layerConfig.geoJSON));
                    layerSysId = gr.update();
                } 
                else {
                    gr.initialize();
                    gr.setValue('order', layerConfig.layerConfiguration.order);
                    gr.setValue('layer_configuration', layerConfig.layerConfiguration.sysID);
                    gr.setValue('geojson', JSON.stringify(layerConfig.geoJSON));
                    gr.setValue('version', versionSysId);
                    layerSysId = gr.insert();
                }

                if (gr.isActionAborted()) {
                    success = false;
                    message = "Insert operation Aborted";
                }

                if(type == 'image') {
                    var content = convertedDXF.SVG;
                    var contentType = 'image/svg+xml';
                    var fileName = 'image';
                    //create the attachment in the sys_attachment table
                    var gsaFloorImage = new GlideSysAttachment();
                    var attachmentId = gsaFloorImage.write(gr, fileName, contentType, content);
                    new FMFloorUtils().setDimentionsFromConverter(layerSysId);
                }
            });
        });
         
        return (new FMFPOperationResult(success, message));
     }

     return {
         'copyVersionLayers': copyVersionLayers,
         // 'getGeoJSONLayerConfiguration': getGeoJSONLayerConfiguration,
         // 'getSVGLayerConfiguration': getSVGLayerConfiguration,
         'checkoutLayer': checkoutLayer,
         'cancelLayerCheckout': cancelLayerCheckout,
         'checkoutAllLayers' : checkoutAllLayers,
         'getConfiguredLayers' : getConfiguredLayers,
         'saveLayer': saveLayer
     };
 };